//
//  main.c
//  films2
//
//  Created by chenyh on 2021/1/20.
//

#include <stdio.h>
#include <stdlib.h> //提供malloc（）原型
#include <string.h> //提供strcpy原型
#define TSIZE 45    //存储片名的数组大小

struct film {
    char    title[TSIZE];
    int     rating;
    struct  film *next; //指向链表中的下一个结构
};

char * s_gets(char * st,int n);
//1、创建链表、将用户输入的数据存储到链表中
//2、显示链表
int main(int argc, const char * argv[]) {
    
    struct film * head = NULL;
    struct film * prev = NULL,* current = NULL;
    char input[TSIZE];
    
    //收集并存储信息
    puts("Enter first movie title:");
    while (s_gets(input,TSIZE) != NULL && input[0] != '\0') {
        //获取用户输入 用户通过键盘模拟EOF或输入一行空行，将推出该循环
        /**
         2、创建链表(单链表)
         2.1、使用malloc()为结构分配足够的空间。
         2.2、存储结构的地址
         2.3、把当前信息拷贝到结构中
                     (prev)     (prev)       (prev)      NULL
         head-> [data]next->[data]next->[data]next->[data]next
         */
        //如果用户进行输入，程序就分配一个结构的空间,并将其地址付给指针变量current：
        current = (struct film *) malloc(sizeof(struct film));
        //链表第一个结构应该存为指针变量head中
        if(head == NULL) //第一个结构
            head = current;
        else
            //随后每个结构的地址应该存储在其前一个结构的next成员中
            prev->next = current; //后续的结构
        current->next = NULL; //标明当前结构是链表最后一个
        strcpy(current->title, input); //
        puts("Enter your rating <0-10>:");
        scanf("%d",&current->rating);
        while (getchar() != '\n') {
            continue;
        }
        puts("Enter next movie title (empty line to stop)):");
        //因为用户在输入下一步电影且程序为新结构分配空间后，当前结构将成为新结构的上一个结构。所以
        //在循环末尾这样设置新的指针
        prev = current;
    }
    
    //显示电影列表
    if (head == NULL) {
        printf("No data entered.");
    }else {
        printf("Here is the movie list:\n");
    }
    
    /**
     1、显示链表
     1.1、显示链表从设置一个 指向第一个结构的指针（名为current）开始。由于头指针（名为head）已经指向链表中的第一个结构
     所以可以用 current = head;
     1.2、根据存储在该结构中next成员中的信息。重新设置current指针指向链表下一个结构。
     current = current->next;
     当显示到链表中最后一个项时，current将被设置为NULL。因为这时链表最后一个结构中的next成员是NULL
     遍历链表时，为何不直接使用head指针，而要重新创建一个新的指针(current)？，因为如果使用head会改变
     head中的值,程序就找不到链表的开始处。
     */
    
    current = head;
    while (current != NULL) {
        printf("Movie: %s Rating: %d\n",current->title,current->rating);
        current = current->next;
    }
    //完成任务，释放已分配的内存
    current = head;
    while (head != NULL) {
        current = head;
        head = current->next;
        free(current);
    }
    printf("Bye!\n");

    return 0;
}
char * s_gets(char * st,int n)
{
    char * ret_val;
    char * find;
    ret_val = fgets(st, n, stdin);
    if (ret_val) {
        find = strchr(st, '\n'); //strchar从st从查找'\n'
        if (find) {
            *find = '\0';
        }else
            while (getchar() != '\n')
                continue;
    }
    return ret_val;
}
